package com.hibase.core.rule.service.ruletable.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.hibase.common.util.EntityUtil;
import com.hibase.core.mybatis.service.BaseServiceImpl;
import com.hibase.core.rule.constant.RuleFieldType;
import com.hibase.core.rule.constant.RuleStatus;
import com.hibase.core.rule.entity.ruletable.RuleTable;
import com.hibase.core.rule.entity.ruletable.RuleTableField;
import com.hibase.core.rule.entity.ruletable.vo.*;
import com.hibase.core.rule.mapper.ruletable.RuleTableMapper;
import com.hibase.core.rule.service.ruletable.RuleTableDataService;
import com.hibase.core.rule.service.ruletable.RuleTableFieldService;
import com.hibase.core.rule.service.ruletable.RuleTableService;
import com.hibase.core.rule.service.ruletableversion.RuleTableVersionService;
import com.hibase.common.exception.HibaseAssert;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 动态规则表 服务实现类
 * </p>
 *
 * @author hufeng
 * @since 2019-06-10
 */
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
@Slf4j
public class RuleTableServiceImpl extends BaseServiceImpl<RuleTableMapper, RuleTable> implements RuleTableService {

    @Autowired
    private RuleTableDataService ruleTableDataService;

    @Autowired
    private RuleTableFieldService ruleTableFieldService;

    @Autowired
    private RuleTableVersionService ruleTableVersionService;

    /**
     * 查询动态规则表列表
     */
    @Override
    public PageInfo<RuleTable> selectRuleTableList(RuleTableSearchVO searchVO) {

        // step 1. 设置查询条件
        QueryWrapper<RuleTable> ruleTableQueryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(searchVO.getName())){
            ruleTableQueryWrapper.like("name",searchVO.getName());
        }
        if (StrUtil.isNotBlank(searchVO.getStatus())){
            ruleTableQueryWrapper.eq("status",searchVO.getStatus());
        }


        PageInfo<RuleTable> page = super.page(searchVO, ruleTableQueryWrapper);
        page.getList().forEach(p->{

            // step 2. 查询相关表字段和表数据数量
            int fieldCount = ruleTableFieldService.count(new QueryWrapper<RuleTableField>().eq("rule_table_id", p.getId()));
            if (RuleFieldType.RANGE_LEFT.getKey().equals(p.getSearchType())){
                p.setSearchType(RuleFieldType.LEFT_OR_RIGHT.getValue());
            }
            if (RuleFieldType.LEFT_OR_RIGHT_AWAY.getKey().equals(p.getSearchType())){
                p.setSearchType(RuleFieldType.LEFT_OR_RIGHT_AWAY.getValue());
            }
            p.setFieldCount(String.valueOf(fieldCount));
        });

        return page;
    }

    /**
     * 改变动态规则表记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRuleTable(RuleTable ruleTable) {

        // step 1. 表名重复校验
        // 新增
        List<RuleTableField> fieldList = new ArrayList<>();
        RuleTable name = super.getOne(new QueryWrapper<RuleTable>().eq("name", ruleTable.getName()));
        HibaseAssert.isNull(name,"新增失败，表名已存在");
        ruleTable.setStatus(RuleStatus.RULE_STATUS_ENABLE.getKey());

        // step 2. 判断查找类型
        if ( !ruleTable.getBeMultiValue() && !ruleTable.getBeFindRange()){
            ruleTable.setSearchType(RuleFieldType.NORMAL_ONE.getKey());

            RuleTableField remarksField = new RuleTableField();
            remarksField.setRuleTableId(ruleTable.getId());
            remarksField.setFieldName("remarks");
            remarksField.setFiledType(RuleFieldType.VALUE.getKey());
            remarksField.setBeEmpty(Boolean.TRUE);
            remarksField.setColumnSort(new BigDecimal(RuleFieldType.REMARK.getKey()));
            remarksField.setRemarks("系统默认字段");
            fieldList.add(remarksField);
        }

        //entity.setName()
        //普通一对多
        if ( ruleTable.getBeMultiValue() && !ruleTable.getBeFindRange()){
            ruleTable.setSearchType(RuleFieldType.NORMAL_MULT.getKey());
            //一对多 需要 优先级
            RuleTableField priorityField = new RuleTableField();
            priorityField.setRuleTableId(ruleTable.getId());
            priorityField.setFieldName("priority");
            priorityField.setFiledType(RuleFieldType.VALUE.getKey());
            priorityField.setBeEmpty(Boolean.FALSE);
            priorityField.setColumnSort(new BigDecimal(RuleFieldType.PRIORITY_SORT.getKey()));
            priorityField.setRemarks("系统默认字段");
            fieldList.add(priorityField);

            RuleTableField remarksField = new RuleTableField();
            remarksField.setId(ruleTable.getId());
            remarksField.setFieldName("remarks");
            remarksField.setFiledType(RuleFieldType.VALUE.getKey());
            remarksField.setBeEmpty(Boolean.TRUE);
            remarksField.setColumnSort(new BigDecimal(RuleFieldType.REMARK.getKey()));
            remarksField.setRemarks("系统默认字段");
            fieldList.add(remarksField);
        }

        //范围一对一
        if ( !ruleTable.getBeMultiValue() && ruleTable.getBeFindRange()){

            ruleTable.setSearchType(RuleFieldType.RANGE_ONE.getKey());
            // 需要范围的字段
            RuleTableField leftField = new RuleTableField();
            leftField.setRuleTableId(ruleTable.getId());
            leftField.setFieldName("range_left");
            leftField.setFiledType(RuleFieldType.RANGE_QUERY.getKey());
            leftField.setBeEmpty(Boolean.FALSE);
            leftField.setColumnSort(new BigDecimal(RuleFieldType.RANGE_SORT_LEFT.getKey()));
            leftField.setRemarks("系统默认字段");
            fieldList.add(leftField);

            RuleTableField rightField = new RuleTableField();
            rightField.setRuleTableId(ruleTable.getId());
            rightField.setFieldName("range_right");
            rightField.setFiledType(RuleFieldType.RANGE_QUERY.getKey());
            rightField.setBeEmpty(Boolean.FALSE);
            rightField.setColumnSort(new BigDecimal(RuleFieldType.RANGE_SORT_RIGHT.getKey()));
            rightField.setRemarks("系统默认字段");
            fieldList.add(rightField);

            RuleTableField remarksField = new RuleTableField();
            remarksField.setId(ruleTable.getId());
            remarksField.setFieldName("remarks");
            remarksField.setFiledType(RuleFieldType.VALUE.getKey());
            remarksField.setBeEmpty(Boolean.TRUE);
            remarksField.setColumnSort(new BigDecimal(RuleFieldType.REMARK.getKey()));
            remarksField.setRemarks("系统默认字段");
            fieldList.add(remarksField);
        }
        //范围一对多
        if ( ruleTable.getBeMultiValue() && ruleTable.getBeFindRange()){
            ruleTable.setSearchType(RuleFieldType.RANGE_MULT.getKey());

            RuleTableField leftField = new RuleTableField();
            leftField.setRuleTableId(ruleTable.getId());
            leftField.setFieldName("range_left");
            leftField.setFiledType(RuleFieldType.RANGE_QUERY.getKey());
            leftField.setBeEmpty(Boolean.FALSE);
            leftField.setColumnSort(new BigDecimal(RuleFieldType.RANGE_SORT_LEFT.getKey()));
            leftField.setRemarks("系统默认字段");
            fieldList.add(leftField);

            RuleTableField rightField = new RuleTableField();
            rightField.setRuleTableId(ruleTable.getId());
            rightField.setFieldName("range_right");
            rightField.setFiledType(RuleFieldType.RANGE_QUERY.getKey());
            rightField.setBeEmpty(Boolean.FALSE);
            rightField.setColumnSort(new BigDecimal(RuleFieldType.RANGE_SORT_RIGHT.getKey()));
            rightField.setRemarks("系统默认字段");
            fieldList.add(rightField);

            RuleTableField priorityField = new RuleTableField();
            priorityField.setRuleTableId(ruleTable.getId());
            priorityField.setFieldName("priority");
            priorityField.setFiledType(RuleFieldType.VALUE.getKey());
            priorityField.setBeEmpty(Boolean.FALSE);
            priorityField.setColumnSort(new BigDecimal(RuleFieldType.PRIORITY_SORT.getKey()));
            priorityField.setRemarks("系统默认字段");
            fieldList.add(priorityField);

            RuleTableField remarksField = new RuleTableField();
            remarksField.setId(ruleTable.getId());
            remarksField.setFieldName("remarks");
            remarksField.setFiledType(RuleFieldType.VALUE.getKey());
            remarksField.setBeEmpty(Boolean.TRUE);
            remarksField.setColumnSort(new BigDecimal(RuleFieldType.REMARK.getKey()));
            remarksField.setRemarks("系统默认字段");
            fieldList.add(remarksField);
        }

        super.store(ruleTable);
        //设置关联id
        fieldList.forEach(p->{
            p.setRuleTableId(ruleTable.getId());
        });
        ruleTableFieldService.storeBatch(fieldList);

    }

    /**
     * 查询动态规则表详情
     */
    @Override
    public RuleTableViewVO viewRuleTable(String id) {

        // step 1. 获取表基础信息
        RuleTable ruleTable = super.getById(id, true);

        int fieldCount = ruleTableFieldService.count(new QueryWrapper<RuleTableField>().eq("rule_table_id", ruleTable.getId()));
        //int dataCount = countTableData(ruleTable.getId());

        ruleTable.setFieldCount(String.valueOf(fieldCount));
        //ruleTable.setDataCount(String.valueOf(dataCount));

        // step 2. 获取表字段集合
        List<RuleTableField> list = ruleTableFieldService.list(new QueryWrapper<RuleTableField>().eq("rule_table_id", ruleTable.getId()).orderByAsc("column_sort"));

        RuleTableViewVO result = EntityUtil.transform(ruleTable, RuleTableViewVO.class);
        if (CollUtil.isNotEmpty(list)){
            result.setFieldList(EntityUtil.transform(list, RuleTableFieldViewVO.class));
        }

        return result;
    }


    /**
     * 删除动态规则表记录
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteRuleTable(List<String> ids) {
        for (String id : ids) {
            QueryWrapper<RuleTableField> wrapper = new QueryWrapper<>();
            wrapper.eq("rule_table_id",id);
            ruleTableFieldService.deleteBy(new QueryWrapper<RuleTableField>().eq("rule_table_id",id));
        }
        super.deleteBy(ids);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void operaRuleTable(List<String> ids, RuleStatus status) {

        // step 1. 查询数据
        Collection<RuleTable> ruleTables = super.listByIds(ids);
        HibaseAssert.isTrue(CollectionUtil.isNotEmpty(ruleTables),"数据不存在");

        ruleTables.forEach(ruleTable->{
            // step 2. 检查状态
            HibaseAssert.isFalse(ruleTable.getStatus().equals(status.getKey()),"重复操作");

            // step 3. 修改状态
            ruleTable.setStatus(status.getKey());
        });

        super.storeBatch(ruleTables);
    }

    /**
     * 编辑表信息和表关联字段
     * @param updateVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRuleTable(RuleTableUpdateVO updateVO) {

        RuleTable ruleTable = EntityUtil.transform(updateVO, RuleTable.class);

        // step 1. 表名重复校验
        // 修改表信息
        RuleTable old = super.getById(ruleTable.getId());
        //todo 上线的表禁止修改 需要遍历版本表的数据
        //HibaseAssert.isTrue(old.getStatus().equals(RuleStatus.RULE_STATUS_CANCEL.getKey()),"修改失败，表已上线");
        RuleTable name = super.getOne(new QueryWrapper<RuleTable>().eq("name", ruleTable.getName()));
        HibaseAssert.isTrue(name==null||name.getId().equals(old.getId()),"修改失败，表名已存在");
        super.store(ruleTable);

        // step 2. 修改表字段信息
        List<RuleTableFieldUpdateVO> fieldList = updateVO.getFieldList();
        List<RuleTableField> tableFieldList = EntityUtil.transform(fieldList, RuleTableField.class);
        QueryWrapper<RuleTableField> wrapper = new QueryWrapper<>();
        wrapper.eq("rule_table_id",ruleTable.getId());
        List<RuleTableField> oldFields = ruleTableFieldService.list(wrapper);

//        boolean isHavePriority = oldFields.stream().allMatch(p -> p.getFieldName().equals("priority"));
//        boolean isHaveRangeLeft = oldFields.stream().allMatch(p -> p.getFieldName().equals("range_left"));
//        boolean isHaveRangeRight = oldFields.stream().allMatch(p -> p.getFieldName().equals("range_right"));
//        boolean isHaveRemarks = oldFields.stream().allMatch(p -> p.getFieldName().equals("remarks"));
//
//        Iterator<RuleTableField> it = oldFields.iterator();
//        while (it.hasNext()) {
//            RuleTableField entity = it.next();
//            if (entity.getFiledType().equals("priority")){
//                isHavePriority = true;
//            }
//            if (entity.getFiledType().equals("range_left")){
//                isHaveRangeLeft= true;
//            }
//            if (entity.getFiledType().equals("range_right")){
//                isHaveRangeRight= true;
//            }
//            if (entity.getFiledType().equals("remarks")){
//                isHaveRemarks= true;
//            }
//
//        }


//        log.info("isHavePriority:",isHavePriority);
//        tableFieldList.removeIf(p -> p.getFieldName().equals("priority"));
//        tableFieldList.removeIf(p -> p.getFieldName().equals("range_left"));
//        tableFieldList.removeIf(p -> p.getFieldName().equals("range_right"));
//        tableFieldList.removeIf(p -> p.getFieldName().equals("remarks"));
//        log.info("tableFieldList ----:{}",tableFieldList.toString());
//        Iterator<RuleTableFieldUpdateVO> iterator = fieldList.iterator();
//        while (iterator.hasNext()) {
//            RuleTableFieldUpdateVO item = iterator.next();
//            if (item.getFieldName().equals("priority")){
//                iterator.remove();
//            }
//            if (item.getFieldName().equals("range_left")){
//                iterator.remove();
//            }
//            if (item.getFieldName().equals("range_right") ){
//                iterator.remove();
//            }
//            if (item.getFieldName().equals("remarks")){
//                iterator.remove();
//            }
//        }

        // step 3. id字段限制添加 优先级字段限制添加
//        HibaseAssert.isFalse(tableFieldList.stream().anyMatch(p->p.getFieldName().equals("priority")),"priority字段为系统默认，不允许添加");
//        HibaseAssert.isFalse(tableFieldList.stream().anyMatch(p->p.getFieldName().equals("range_left")),"range_left字段为系统默认，不允许添加");
//        HibaseAssert.isFalse(tableFieldList.stream().anyMatch(p->p.getFieldName().equals("range_right")),"range_right字段为系统默认，不允许添加");
//        HibaseAssert.isFalse(tableFieldList.stream().anyMatch(p->p.getFieldName().equals("remarks")),"remarks字段为系统默认，不允许添加");
        // todo 新增默认字段 范围range_left,range_right, remark 优先级 字段默认存在， 不能删除或添加
        //Optional<RuleTableField> isHavePriority = tableFieldList.stream().filter(p -> p.getFieldName().equals("priority")).findFirst();
//        if (!isHavePriority) {
//            // 不存在进行新增
//            RuleTableField priorityField = new RuleTableField();
//            priorityField.setFieldName("priority");
//            priorityField.setFiledType(RuleFieldType.VALUE.getKey());
//            priorityField.setBeEmpty(Boolean.FALSE);
//            priorityField.setColumnSort(new BigDecimal(RuleRangeTypeEnum.PRIORITY_SORT.getKey()));
//            priorityField.setRemarks("系统默认字段");
//            tableFieldList.add(priorityField);
//        }
//        //range_left
//       // Optional<RuleTableField> isHaveRangeLeft = tableFieldList.stream().filter(p -> p.getFieldName().equals("range_left")).findFirst();
//        if (!isHaveRangeLeft) {
//            // 不存在进行新增
//            RuleTableField priorityField = new RuleTableField();
//            priorityField.setFieldName("range_left");
//
//            priorityField.setFiledType(RuleFieldType.VALUE.getKey());
//            priorityField.setBeEmpty(Boolean.FALSE);
//            priorityField.setColumnSort(new BigDecimal(RuleFieldType.RANGE_SORT_LEFT.getKey()));
//            priorityField.setRemarks("系统默认字段");
//            tableFieldList.add(priorityField);
//        } else {
//
//        }
//        //range_right
//        //Optional<RuleTableField> isHaveRangeRight = tableFieldList.stream().filter(p -> p.getFieldName().equals("range_right")).findFirst();
//        if (!isHaveRangeRight) {
//            // 不存在进行新增
//            RuleTableField priorityField = new RuleTableField();
//            priorityField.setFieldName("range_right");
//            priorityField.setFiledType(RuleFieldType.VALUE.getKey());
//            priorityField.setBeEmpty(Boolean.FALSE);
//            priorityField.setColumnSort(new BigDecimal(RuleRangeTypeEnum.RANGE_RIGHT.getKey()));
//            priorityField.setRemarks("系统默认字段");
//            tableFieldList.add(priorityField);
//        }
//
//        //remark
//        //Optional<RuleTableField> isHaveRemark = tableFieldList.stream().filter(p -> p.getFieldName().equals("remark")).findFirst();
//        if (!isHaveRemarks) {
//            // 不存在进行新增
//            RuleTableField priorityField = new RuleTableField();
//            priorityField.setFieldName("remarks");
//            priorityField.setFiledType(RuleFieldType.VALUE.getKey());
//            priorityField.setBeEmpty(Boolean.FALSE);
//            priorityField.setColumnSort(new BigDecimal(RuleRangeTypeEnum.REMARK.getKey()));
//            priorityField.setRemarks("系统默认字段");
//            tableFieldList.add(priorityField);
//        }

        // step 4. 设置表字段关联表头id
        tableFieldList.forEach(p -> p.setRuleTableId(ruleTable.getId()));
        log.info("tableFieldList:{}",tableFieldList.toString());
        ruleTableFieldService.storeBatch(tableFieldList);


    }
}
